package com.guoqi.marrydate

import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*


/**
 * 作者    GUOQI
 * 时间    2019/4/11 16:03
 * 描述
 */
object DateUtil {

    /**
     * 转换日期格式
     */
    fun convertDateFormat(dateStr: String, oldPattern: String, newPattern: String): String {
        val formatterOld = SimpleDateFormat(oldPattern)
        var newDate = formatterOld.parse(dateStr);
        val formatter = SimpleDateFormat(newPattern)
        return formatter.format(newDate)
    }


    /**
     * 获取前n天日期、后n天日期
     *
     * @param distanceDay 前几天 如获取前7天日期则传-7即可；如果后7天则传7
     * @return
     */
    fun getNDate(nowDate: String, distanceDay: Int): String {
        val dft = SimpleDateFormat("yyyy-MM-dd")
        val beginDate = dft.parse(nowDate)
        val date = Calendar.getInstance()
        date.time = beginDate
        date.set(Calendar.DATE, date.get(Calendar.DATE) + distanceDay)
        var endDate: Date? = null
        try {
            endDate = dft.parse(dft.format(date.time))
        } catch (e: ParseException) {
            e.printStackTrace()
        }
        return dft.format(endDate)
    }

    /**
     * 获取任意时间的下一个月
     */
    fun getNextMonth(nowDateStr: String): String {
        val cal = Calendar.getInstance()
        var year = DateUtil.convertDateFormat(nowDateStr, "yyyy-MM-dd", "yyyy").toInt()
        var month = DateUtil.convertDateFormat(nowDateStr, "yyyy-MM-dd", "M").toInt()
        var day = DateUtil.convertDateFormat(nowDateStr, "yyyy-MM-dd", "d").toInt()
        cal.set(year, month, Calendar.DATE)
        if (month == 12) {
            month = 1
            year++
        } else {
            month++
        }
        //下个月同一天 会出现 2019-04-31 不存在跳过此月
        val nextMonthOfDays = getDaysOfMonth(cal.time)
        if (day > nextMonthOfDays) {
            if (month + 1 > 12) {
                month = 1
                year++
            } else {
                month++
            }
        }
        val monthStr =
                if (month < 10) {
                    "0$month"
                } else {
                    month.toString()
                }
        val dayStr =
                if (day < 10) {
                    "0$day"
                } else {
                    day.toString()
                }
        return "$year-$monthStr-$dayStr"
    }


    fun getDaysOfMonth(date: Date): Int {
        val calendar = Calendar.getInstance()
        calendar.time = date
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
    }

    /**
     * 获取 2 个时间的自然年历的时间间隔
     *
     * @param nextDate     后面的时间，需要大于 previousDate
     * @param previousDate 前面的时间
     * @return [年, 月, 日, 小时, 分钟, 秒]的数组
     */
    fun getNatureDiff(nextDate: Calendar, previousDate: Calendar): String {
        var year = nextDate.get(Calendar.YEAR) - previousDate.get(Calendar.YEAR)
        var month = nextDate.get(Calendar.MONTH) - previousDate.get(Calendar.MONTH)
        var day = nextDate.get(Calendar.DAY_OF_MONTH) - previousDate.get(Calendar.DAY_OF_MONTH)
        var hour = nextDate.get(Calendar.HOUR_OF_DAY) - previousDate.get(Calendar.HOUR_OF_DAY)// 24小时制
        var min = nextDate.get(Calendar.MINUTE) - previousDate.get(Calendar.MINUTE)
        var second = nextDate.get(Calendar.SECOND) - previousDate.get(Calendar.SECOND)

        var hasBorrowDay = false// "时"是否向"天"借过一位

        if (second < 0) {
            second += 60
            min--
        }

        if (min < 0) {
            min += 60
            hour--
        }

        if (hour < 0) {
            hour += 24
            day--

            hasBorrowDay = true
        }

        if (day < 0) {
            // 计算截止日期的上一个月有多少天，补上去
            val tempDate = nextDate.clone() as Calendar
            tempDate.add(Calendar.MONTH, -1)// 获取截止日期的上一个月
            day += tempDate.getActualMaximum(Calendar.DAY_OF_MONTH)

            // nextDate是月底最后一天，且day=这个月的天数，即是刚好一整个月，比如20160131~20160229，day=29，实则为1个月
            if (!hasBorrowDay
                    && nextDate.get(Calendar.DAY_OF_MONTH) === nextDate.getActualMaximum(Calendar.DAY_OF_MONTH)// 日期为月底最后一天

                    && day >= nextDate.getActualMaximum(Calendar.DAY_OF_MONTH)) {// day刚好是nextDate一个月的天数，或大于nextDate月的天数（比如2月可能只有28天）
                day = 0// 因为这样判断是相当于刚好是整月了，那么不用向 month 借位，只需将 day 置 0
            } else {// 向month借一位
                month--
            }
        }

        if (month < 0) {
            month += 12
            year--
        }
        var r = ""
        if (year > 0) {
            r += """${year}年"""
        }
        if (month > 0) {
            r += """${month}个月"""
        }
        if (day > 0) {
            r += """${day}天"""
        }
        return r
    }

    @JvmStatic
    fun main(args: Array<String>) {
        val str = "2019-08-13"
        val sdf = SimpleDateFormat("yyyy-MM-dd")
        val date = sdf.parse(str)
        val calendar = Calendar.getInstance()
        calendar.time = date
        println(getNatureDiff(Calendar.getInstance(), calendar))
    }

}
